#include "CircuitGraph.h"

CircuitGraph::CircuitGraph()
{

}
void CircuitGraph::setEdge(int from,int to)
{
    if(gates[from].gate->type!=2&&gates[to].gate->type!=1 && gates[to].gate->curlen<gates[to].gate->maxlen)
    {
        EdgeNode *p=NULL;
        EdgeNode *q=NULL;//指向p节点前面的那个VNode节点
        EdgeNode *newEdge=new EdgeNode;
        newEdge->next=NULL;
        if(this->gates[from].first!=NULL)
            p=this->gates[from].first;//初始化该边指向VNode节点的第一条边
        while(p!=NULL)
        {
            if(p->adjVex==to)//重复边检验
            {
                //注意野指针，此处因为没有处理野指针出现过程序崩溃
                newEdge=NULL;
                delete newEdge;
                return;
            }
            q=p;
            p=p->next;
        }
        this->gates[to].gate->from[this->gates[to].gate->curlen]=from;
        this->gates[to].gate->curlen++;//被指向的门的输入个数加1
        this->gates[to].gate->indegree++;//被指向的节点入度加1
        if(q==NULL)//如果VNode节点没有第一条边
        {
            this->gates[from].first=newEdge;
            newEdge->adjVex=to;
            return;
        }
        newEdge->adjVex=to;
        q->next=newEdge;
    }
}

void CircuitGraph::topology()//拓扑赋值
{
    QStack<VNode*> stk;
    EdgeNode *p;
    for(int i=0;i<gates.length();i++ )
    {
        if(this->gates[i].gate->type!=1)
        {
            this->gates[i].gate->indegree=this->gates[i].gate->curlen;
        }
        else
        {
             this->gates[i].gate->indegree=0;
        }
    }
    //将入度为零的节点序号压入栈中
    for(int i=0;i<gates.length();i++ )
    {
        if(this->gates[i].gate->indegree==0)
            stk.push(&this->gates[i]);
    }
    //当栈不空时
    while(!stk.isEmpty())
    {
        //栈顶元素出栈
        VNode* temp=stk.top();
        stk.pop();
        temp->gate->indegree=-1;
        //遍历所以有邻接点，所有点入度减一
        p=temp->first;
        while(p!=NULL)
        {
            //把父节点的输出赋给每个子节点作为输入
            gates[p->adjVex].gate->Inputs[gates[p->adjVex].gate->indegree-1]=temp->gate->output;
            //入度减一
            this->gates[p->adjVex].gate->indegree--;
            //如果节点入度减到0，说明不会再有输入了，此时计算他的output，并入栈
            if(gates[p->adjVex].gate->indegree==0)
            {
               gates[p->adjVex].gate->DoSimulate();
                stk.push(&this->gates[p->adjVex]);
            }
            p=p->next;
        }
    }
}
QString CircuitGraph::zhenzhibiao()
{
    QString zhenzhibiao;
    QStack<VNode*> stk;
    EdgeNode *p;
    for(int i=0;i<gates.length();i++ )
    {
        if(this->gates[i].gate->type!=1)
        {
            this->gates[i].gate->indegree=this->gates[i].gate->curlen;
        }
        else
        {
             this->gates[i].gate->indegree=0;
        }
    }
    //将入度为零的节点序号压入栈中
    for(int i=0;i<gates.length();i++ )
    {
        if(this->gates[i].gate->indegree==0)
            stk.push(&this->gates[i]);
    }
    //当栈不空时
    while(!stk.isEmpty())
    {
        //栈顶元素出栈
        VNode* temp=stk.top();
        stk.pop();
        temp->gate->indegree=-1;
        //遍历所以有邻接点，所有点入度减一
        p=temp->first;
        while(p!=NULL)
        {
            //把父节点的输出赋给每个子节点作为输入
            gates[p->adjVex].gate->Inputs[gates[p->adjVex].gate->indegree-1]=temp->gate->output;
            //入度减一
            this->gates[p->adjVex].gate->indegree--;
            //如果节点入度减到0，说明不会再有输入了，此时计算他的output，并入栈
            if(gates[p->adjVex].gate->indegree==0)
            {

               gates[p->adjVex].gate->DoSimulate();
               stk.push(&this->gates[p->adjVex]);
               if(gates[p->adjVex].gate->type==2)
               {
                    QString tempstring=QString::number(gates[p->adjVex].gate->output, 10);
                    zhenzhibiao+=tempstring;
                    zhenzhibiao+=" ";
               }
            }
            p=p->next;
        }
    }
    return zhenzhibiao;
}
//
int CircuitGraph::selectGate_1(int mouse_x,int mouse_y)
{
   int i;
   int draw_temp_line_flag=0;
    for(i=0;i<this->gates.length();i++)
    {
        if(mouse_x > this->gates[i].gate->gate_x && mouse_x <this->gates[i].gate->gate_x+50&&mouse_y > this->gates[i].gate->gate_y && mouse_y <this->gates[i].gate->gate_y+50)
        {
            if(this->gates[i].gate->clickState==0 )
            {
                this->gates[i].gate->clickState=1;
                draw_temp_line_flag=1;
            }
        }
        else  this->gates[i].gate->clickState=0;
    }
    return draw_temp_line_flag;
}
void CircuitGraph::selectGate_2(int mouse_x,int mouse_y)
{
    int i;
    bool clearFlag=true;
    for(i=0;i<this->gates.length();i++)
    {
        if(mouse_x > this->gates[i].gate->gate_x && mouse_x <this->gates[i].gate->gate_x+50&&mouse_y > this->gates[i].gate->gate_y && mouse_y <this->gates[i].gate->gate_y+50)
        {
            clearFlag=false;//
            if(this->gates[i].gate->clickState==1)//如果之前press了这个按钮
                this->gates[i].gate->clickState=2;
            else//如果之前没press这个按钮，考虑连接两个门
                this->gates[i].gate->clickState=3;
            break;
        }
    }
    if(clearFlag)
    {
         for(int j=0;j<this->gates.length();j++)
             this->gates[j].gate->clickState=0;
    }
}

void CircuitGraph::gateMove(int x,int y,int i)
{
    gates[i].gate->gate_x+=(x-gates[i].gate->gate_x);
    gates[i].gate->gate_y+=(y-gates[i].gate->gate_y);
}
